from django.contrib.auth import get_user_model
from django.contrib.auth.hashers import check_password
from rest_framework.generics import ListAPIView
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination
from rest_framework.response import Response
from rest_framework.views import APIView

from api import models, serializer
from api.extensions.auth import JwtAuthorizationAuthentication, JwtQueryParamAuthentication
from utils.jwt_auth import create_token

User = get_user_model()  # 获取系统用户模型

class LoginView(APIView):
    authentication_classes = []

    def post(self, request):
        username = request.data.get('username')
        pwd = request.data.get('password')
        # 用户 密码 验证
        user_obj = User.objects.filter(username=username).first()

        if not user_obj:
            return Response({'code': 2001, 'error': '用户名或密码错误'})

        if not check_password(pwd, user_obj.password):
            return Response({'code': 2002, 'error': '用户名或密码错误'})
        # 字典格式设置token中带的内容，timeout超时时间默认30分钟
        token = create_token({"id": user_obj.id, 'name': user_obj.username})

        return Response({'code': 1001, 'data': token})

class DemoTokenView(APIView):
    # authentication_classes = [JwtQueryParamAuthentication, ] # 通过url传递token
    authentication_classes = [JwtAuthorizationAuthentication, ]  # 通过Authorization请求头传递token

    def get(self, request, *args, **kwargs):
        print('使用在请求头加上 Authorization："jwt '+request.auth+'"')
        print(request.user)

        return Response(request.user)


# class IndexView(APIView):
#     """测试系统是否正常"""
#
#     def get(self, request, *args, **kwargs):
#         return Response('API is OK!')


class ArticleView(APIView):
    """
    delete:
    删除指定图书.
    """

    def get(self, request, *args, **kwargs):
        """
        查询文章列表
        带pk则查询指定文章
        """
        pk = kwargs.get('pk')
        if not pk:
            queryset = models.Article.objects.all()
            # 分页对象
            page_object = PageNumberPagination()
            # 调用分页对象对数据分页
            result = page_object.paginate_queryset(queryset, request, self)
            # 序列化分页后取得的一部分数据
            ser = serializer.ArticleSerializer(instance=result, many=True)
            # return Response(ser.data)  # 仅数据
            # return page_object.get_paginated_response(ser.data)  # 数据+分页信息
            return Response({'count': page_object.page.paginator.count, 'result': ser.data})  # 自定义返回格式+数据

        obj = models.Article.objects.filter(pk=pk).first()
        ser = serializer.ArticleSerializer(instance=obj)
        return Response(ser.data)

    # 和GET使用不同序列化器
    def post(self, request, *args, **kwargs):
        """添加书籍,并把关联的详情表数据一起添加"""
        ser = serializer.FormNewArticleSerializer(data=request.data)
        ser_detail = serializer.ArticleDetailSerializer(data=request.data)
        if ser.is_valid() and ser_detail.is_valid():
            # 用户id不需要前端提供，应获取当前登录状态用户id,这里暂写死
            article_obj = ser.save(author_id=1)
            ser_detail.save(article=article_obj)
            return Response(ser.data)
        return Response(ser.errors)

    def put(self, request, *args, **kwargs):
        """书籍字段需全部提供才更新"""
        pk = kwargs.get('pk')
        article_object = models.Article.objects.filter(id=pk).first()
        ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        return Response(ser.errors)

    def patch(self, request, *args, **kwargs):
        """提供个别需更新的字段值，局部更新 partial=True"""
        pk = kwargs.get('pk')
        article_object = models.Article.objects.filter(id=pk).first()
        ser = serializer.FormNewArticleSerializer(instance=article_object, data=request.data, partial=True)
        if ser.is_valid():
            ser.save()
            return Response(ser.data)
        return Response(ser.errors)

    def delete(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        models.Article.objects.filter(id=pk).delete()
        return Response('删除成功')


class ArticlesView(ListAPIView):
    """ListAPIView 可直接使用全局settings中配置的分页器，"""
    authentication_classes = []
    queryset = models.Article.objects.all()
    serializer_class = serializer.FormNewArticleSerializer
